package com.mjk.common.core.jdbc.service.log;


import com.mjk.common.core.jdbc.service.idgenerator.IdGenerateType;
import com.mjk.common.core.jdbc.service.log.model.BeeLogModel;
import com.mjk.common.core.jdbc.service.plus.idbservice.BaseDBService;
import com.mjk.common.core.redis.datatype.RedisUtils;
import com.mjk.common.tools.logger.BizLogger;
import com.mjk.common.util.ObjectUtils;
import lombok.Getter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.concurrent.*;

/**
 * 全局日志服务类
 * @author Administrator
 *
 */
@Component
public class BeeLogContentHolder {
	private final BaseDBService baseDBService;
	private final RedisTemplate redisTemplate;
	
	private static final String LOG_KEY = "logkey";
    //public static final ThreadLocal<Boolean> needLog = new ThreadLocal<Boolean>();
	/**
	 * 队列
	 */
	@Getter
	private final BlockingQueue<BeeLogModel> queue;
	/**
	 * 线程池
	 */
	private final ExecutorService pool;
	
	private volatile boolean running;	
	
	public BeeLogContentHolder(RedisTemplate redisTemplate, BaseDBService baseDBService) {
		
		this.running = true;
        int MAX_QUERE_NUMBER = 1000;
		this.queue = new LinkedBlockingQueue<>(MAX_QUERE_NUMBER);
        int MAX_POOL_SIZE = 5;
		this.pool = Executors.newFixedThreadPool(MAX_POOL_SIZE, new CustomizableThreadFactory("BeeLogServcie"));
		this.redisTemplate = redisTemplate;
		this.baseDBService = baseDBService;
	}

	public void put(final BeeLogModel model)  {
			try {
				//if(needLog.get())//需要记录日志
					this.queue.add(model);
			}catch(Exception e) {
				BizLogger.error(e);
			}	
	}
	
	@PostConstruct
	public void init() {
		this.pool.execute(() -> {
            while(running){
                try {
                    BeeLogModel dto = queue.take();
                    dto.setId(IdGenerateType.AUTO_SNOWFLAKE.getGenerator().getId(dto));
					dto.setCreateTime(LocalDateTime.now());
                    baseDBService.save(dto);
                } catch (InterruptedException e) {
					//线程不能中断
					//Thread.currentThread().interrupt();
                    BizLogger.error(e);
                }
            }
        });
	}

	@PreDestroy
	public void destroy() throws InterruptedException {
		this.running = false;
		this.pool.shutdown();
		if (!this.pool.awaitTermination(5L, TimeUnit.SECONDS)) {
			BizLogger.warn("......BeeLogServcie: Exceed max timeout for waiting shutdown, ready force close pool.");
			this.pool.shutdownNow();
		}
	}
}
